/*
 Developer: John Archer (john.archer.jpa@gmail.com)
 
 This file is part of VTBuilder.

 VTBuilder is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License.

 VTBuilder is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with VTBuilder.  If not, see <http://www.gnu.org/licenses/>.
 */
package core.tasks.pack;

import core.sb.s.Seq;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class SPartPack extends Thread {

    public ArrayList<Seq> pOut = new ArrayList<Seq>();
    private final CountDownLatch stopLatch;
    private List<Seq> pIn;
    private HashMap<String, ArrayList<Integer>> lib;
    private int lengthOfTemplate;
    private double kt;
    public SPartPack(CountDownLatch stopLatch, List<Seq> pIn, HashMap<String, ArrayList<Integer>> wm, int lengthOfTemplate, double kt) {
        this.stopLatch = stopLatch;
        this.pIn = pIn;
        this.lib = wm;
        this.lengthOfTemplate = lengthOfTemplate;
        this.kt = kt;
    }

    public void run() {
        partition();
        stopLatch.countDown();
    }
    //used in read partitioning - very quick heuristic here
    //im not looking in a single window at end
    //im looking for any window
    //so indels in a single window not so important as a diff window can be used if they exist

    private void partition() {
        int df;
        boolean[] sHt;
        ArrayList<Integer>[] sdf;
        HashMap<Integer, Integer> hsh = new HashMap<Integer, Integer>(250);
        int mD;
        int mF;
        int hts;
        int freq;
        for (int s = 0; s < pIn.size(); s++) {
            double lengthRatio = (double)pIn.get(s).dna.length() / lengthOfTemplate;
            if(lengthRatio>=kt){
                mD=0;mF=0;
                String kmer;
                sHt = new boolean[pIn.get(s).dna.length() - 10];
                sdf = new ArrayList[sHt.length];
                hsh.clear();
                for (int k = 0; k < sHt.length; k++) {
                    if (lib.containsKey(pIn.get(s).dna.substring(k, k + 10))) {
                        kmer = pIn.get(s).dna.substring(k, k + 10);
                        sdf[k] = new ArrayList();
                        for (int t : lib.get(kmer)) {
                            sdf[k].add(df = t - k);
                            if(hsh.get(df)==null){hsh.put(df, 1);}
                            else{
                                freq = hsh.get(df)+1;
                                if(freq>mF){mF=freq;mD=df;}
                                hsh.put(df, freq);
                            }
                        }
                    }
                }

                int upperBound = mD + 10;
                int lowerBound = mD - 10;
                hts = 0;
                for (int c = 0; c < sdf.length; c++) {
                    if (sdf[c] != null) {
                        inner:
                        for (int i : sdf[c]) {
                            if (sHt[c] = (i < upperBound && i > lowerBound)) {
                                break inner;
                            }
                        }
                    }
                }
                int c = 0;
                while (c < sHt.length) {
                    if (sHt[c++]) {
                        hts++;
                    }
                }
                //if 80% of the smaller seq is the same as the longer one
                if (hts > kt * sHt.length) {
                    pOut.add(pIn.get(s));
                    pIn.set(s, null);
                }
            }
        }
    }
}